package scau.osdesign.service;

import javafx.application.Platform;
import scau.osdesign.LaunchMain;
import scau.osdesign.model.Fork;
import scau.osdesign.model.Philosopher;
import scau.osdesign.view.ViewArranger;

import java.util.Vector;

/**
 * Description:本程序实现有一定概率发生死锁的情况
 */
public class DeadLockSim extends Simer {
    public DeadLockSim(){}
    static public int PHILOSOPHER_NUMBER = 5;
    static public int FORK_NUMBER = 5;
    public static Vector vector = new Vector<String>();

    @Override
    public void play(Philosopher[] philosophers,Fork[] forks){
        for(int i = 0 ;i < FORK_NUMBER;i++){
            Fork fork = new Fork();
            forks[i] = fork;
        }
        //1.初始化哲学家
        for(int i = 0;i < philosophers.length ;i++){
            Philosopher philosopher = new Philosopher(i) {
                @Override
                public void run() {
                        while(true){
                            try {
                                System.out.println(this.isInterrupted());
                                vector.addElement("我是第"+(this.getPhiId()+1)+"号哲学家,我正在思考");
                                this.thinking();
                                while(isPaused){this.waitSelf();}
                                if(this.isInterrupted()){return;}

                                vector.addElement("我是第"+(this.getPhiId()+1)+"号哲学家,我在等待叉子");
                                this.waiting();
                                while(isPaused){this.waitSelf();}
                                if(this.isInterrupted()){return;}

                                forks[this.getPhiId()].getLock().acquire();
                                this.getLeftFork(this.getPhiId());
                                while(isPaused){this.waitSelf();}
                                if(this.isInterrupted()){return;}

                                forks[(this.getPhiId()+1)%FORK_NUMBER].getLock().acquire();
                                this.getRightFork((this.getPhiId()+1)%FORK_NUMBER);
                                while(isPaused){this.waitSelf();}
                                if(this.isInterrupted()){return;}

                                vector.addElement("我是第"+(this.getPhiId()+1)+"号哲学家,我得到了左右的叉子，正在就餐");
                                this.eating();
                                while(isPaused){this.waitSelf();}
                                if(this.isInterrupted()){return;}

                                forks[this.getPhiId()].getLock().release();
                                this.releaseLeftFork();
                                while(isPaused){this.waitSelf();}
                                if(this.isInterrupted()){return;}

                                forks[(this.getPhiId()+1)%FORK_NUMBER].getLock().release();
                                this.releaseRightFork();
                                while(isPaused){this.waitSelf();}
                                if(this.isInterrupted()){return;}

                                vector.addElement("我是第"+(this.getPhiId()+1)+"号哲学家,我吃完了，正在放下叉子");
                                this.finish();
                                if(this.isInterrupted()){return;}

                                isDeadLock(forks);
                            }catch (InterruptedException e){
                                e.printStackTrace();
                            }
                        }
                    }

            };
            philosophers[i] = philosopher;
        }
        //2.叉子队列初始化
        //3.开始模拟
        for(int i =0;i<PHILOSOPHER_NUMBER;i++){
            philosophers[i].start();
        }
        while(true){
            try{
                while(isPaused){
                    waitSelf();
                }
                if(this.isInterrupted()){return;}
                Thread.sleep(100);//采样
                Platform.runLater(()->{
                    ViewArranger.updateState(philosophers,forks,vector);
                    vector.clear();
                });
            }catch (InterruptedException e){
                e.printStackTrace();
            }
        }
    }

    static public void isDeadLock(Fork[] forks){
        System.out.print("当前叉子的情况为:");
        int cnt = 0;
        for(int i = 0;i<FORK_NUMBER;i++){
            System.out.print(i+"号叉子:"+forks[i].getLock().availablePermits()+" ");
        }
        System.out.println();
    }

    @Override
    public void run() {
        play(LaunchMain.philosophers,LaunchMain.forks);
    }

}
